package org.xmap.util;
public class BitReader {
    /**
     * 位掩码表。
     */
    private static int[] mask = new int[32];
    /**
     * 从数据源(int类型)读取起始位到结束位的值。
     * @param begin int 起始位。
     * @param end int 结束位。
     * @param source int 数据源。
     * @return int 读取的值。
     */
    public static int readBitsFromInt(int begin, int end, int source) {
        if (BitReader.mask[1] == 0) { // 构建掩码表
            BitReader.mask[1] = 1;
            for (int i = 2; i < 32; i++) {
                BitReader.mask[i] = (BitReader.mask[i - 1] << 1) + 1;
            }
        }
        if (begin > end) { // 交换两个变量的值。
            begin = begin + end;
            end = begin - end;
            begin = begin - end;
        }
        if (begin < 0) { // 下限限制
            begin = 0;
        }
        if (end > 31) { // 上限限制
            end = 31;
        }
//        复习一下java的移位
//        移位的范围在32位以内
//        针对补码:
//        1.<<是带符号位左移，高位丢失，低位补0
//        2.>>是不带符号位右移(对于负数，高位补1，可以认为用最高位来补位，对于负数，最高位为1)
//        3.>>>是带符号位右移，高位补0，低位丢失
//        其实移位是对补码来进行操作的，这样可以解释为什么右移-1会永远是-1，因为-1的补码全是1，>>时，不会发生变化。
        source >>>= begin; // 清除低位的值
        source &= BitReader.mask[end - begin + 1]; // 得到想要的值
        return source;
    }
}
